package com.book.lizhi.read;

import java.util.List;
import java.util.Vector;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.content.Intent;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.TextView;
import android.widget.Toast;
import cn.waps.AppConnect;

import com.alibaba.fastjson.JSON;
import com.android.volley.VolleyError;
import com.book.lizhi.AppApplication;
import com.book.lizhi.AppConfig;
import com.book.lizhi.BaseActivity;
import com.book.lizhi.R;
import com.book.lizhi.constants.Constants;
import com.book.lizhi.database.BookShelfInfo;
import com.book.lizhi.database.DataBaseMannager;
import com.book.lizhi.http.OnHttpListener;
import com.book.lizhi.model.ChapterModel;
import com.book.lizhi.model.ContentModel;
import com.book.lizhi.model.DetailBookModel;
import com.book.lizhi.ui.BookshelfActivity;
import com.book.lizhi.util.AppLog;
import com.book.lizhi.util.FileUtil;
import com.book.lizhi.util.Util;
import com.book.lizhi.widget.AppTitleView;
import com.book.lizhi.widget.AppTitleView.OnTitleListener;
import com.book.lizhi.widget.HttpAsyncLayout;
import com.book.lizhi.widget.HttpAsyncLayout.OnHttpAsyncListner;

public class ReadActivity extends BaseActivity implements Callback {

	public static final int BOOKMARK_REQUEST_CODE = 1112;
	public static final int CHAPTER_REQUEST_CODE = 1113;
	public static final int MARK_CHAPTER_REQUEST_CODE = 1120;
	public static final int RESET_REQUEST_POSITION = 1119;
	public static final int READ_NEXT_CHAPTER = 1121;
	public static final int READ_PRE_CHAPTER = 1122;
	public static final int CHANGE_TEXT_SIZE = 1123;
	public static final int CHAGE_BACKGROUD = 1124;
	public static final int LOAD_NEXT_CHAPTER = 1125;

	private static final int NIGT_MODEL = 1114;
	private static final int DAY_MODEL = 1115;
	private static final int READ_CHAPTER = 1116;
	private static final int READ_NEXT = 1117;
	private static final int READ_PRE = 1118;

	private static final int CACHE_COUNT = 3;
	public static final int BUY_BOOK = 1119;

	private HttpAsyncLayout mAsyncLayout;
	private ReadView mReadView;
	private TextView mReadProgressView;
	private View mNoPointsView;
	private View mConsumeView;

	private List<ChapterModel> mChapterModels;
	private ContentModel mNetBookModel;
	private DetailBookModel mDetailModel;
	private ReadFactory mFactory;
	private Paint mPaint;

	private AppTitleView mTitleView;
	private ReadMenu mReadMenu;
	private ConsumeMenu mConsumeMenu;

	private Handler mHandler = new Handler(this);

	private int mVisibleHeight;
	private int mVisibleWidth;
	private int mTextSize = 22;

	private boolean isStop = false;
	// 已经下载章节索引
	private volatile int mLCIndex = 0;
	// 当前正读章节索引
	private volatile int mRCIndex = 0;

	private ExecutorService mExecutorService = Executors.newFixedThreadPool(1);

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// requestWindowFeature(Window.FEATURE_NO_TITLE);
		// getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
		setContentView(R.layout.activity_read);

		initData();
	}

	@Override
	protected void onNewIntent(Intent intent) {
		super.onNewIntent(intent);
		AppLog.e("into--[onNewIntent]");
		mRCIndex = intent.getIntExtra(Constants.CURRENT_CHAPTER, 0) - 1;
		if (mLCIndex < mRCIndex) {
			mLCIndex = mRCIndex;
		}

		mHandler.sendEmptyMessage(READ_NEXT_CHAPTER);
	}

	private void initData() {
		mDetailModel = JSON.parseObject(JSON.toJSONString(AppApplication.instance.currentBookModel), DetailBookModel.class);
		mChapterModels = mDetailModel.chapterModels;
		AppApplication.instance.currentBookModel = mDetailModel;

		DisplayMetrics dm = new DisplayMetrics();
		dm = this.getResources().getDisplayMetrics();
		mVisibleWidth = (int) (dm.widthPixels - getResources().getDimension(R.dimen._40));
		mVisibleHeight = (int) (dm.heightPixels - getResources().getDimension(R.dimen._40));

		initUI();
	}

	private void initUI() {
		mAsyncLayout = (HttpAsyncLayout) findViewById(R.id.http_async_layout);
		mReadProgressView = (TextView) findViewById(R.id.read_progress_view);
		mNoPointsView = findViewById(R.id.show_no_points_view);
		mNoPointsView.setVisibility(View.GONE);
		mConsumeView = findViewById(R.id.read_get_points_view);

		initReadParams();
		initMenu();
		initRead();

	}

	private void initReadParams() {
		mTextSize = Util.getIntBySharePreference(Constants.READ_TEXT_SIZE);
		if (mTextSize == 0) {
			mTextSize = 22;
		}

		TextView textView = new TextView(this);
		Typeface typeface = Typeface.createFromAsset(getAssets(), "xin_hei.otf");
		textView.setTypeface(typeface);
		textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextSize);

		mPaint = textView.getPaint();
		mReadView = new ReadView(this, mPaint);
		if (Util.getBooleanBySharePreference(Constants.READ_MODE)) {
			int index = Util.getIntBySharePreference(Constants.READ_BACKGROUD);
			int backgroud = 0;
			switch (index) {
			case 0:
				backgroud = getResources().getColor(R.color.backgroud_0);
				break;
			case 1:
				backgroud = getResources().getColor(R.color.backgroud_1);

				break;
			case 2:
				backgroud = getResources().getColor(R.color.backgroud_2);

				break;
			case 3:
				backgroud = getResources().getColor(R.color.backgroud_3);

				break;

			default:
				break;
			}
			mPaint.setColor(getResources().getColor(R.color.read_color));
			mReadView.setBackgroudColor(backgroud);
			mNoPointsView.setBackgroundColor(backgroud);
		} else {
			mPaint.setColor(getResources().getColor(R.color.read_color_night));
			mReadView.setBackgroudColor(getResources().getColor(R.color.backgroud_4));
		}
		((ViewGroup) findViewById(R.id.up_container)).addView(mReadView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);

		mFactory = new ReadFactory(mVisibleWidth, mVisibleHeight, mReadView.getLineHeight(), mPaint);
	}

	private void initMenu() {
		mTitleView = (AppTitleView) findViewById(R.id.title_view);
		mTitleView.setVisibility(View.GONE);
		mReadMenu = new ReadMenu(this, mHandler, mTitleView, mAsyncLayout);
		mConsumeMenu = new ConsumeMenu(this, mAsyncLayout, mHandler);
	}

	private void initRead() {
		mRCIndex = Integer.parseInt(mDetailModel.rcIndex);
		mLCIndex = Integer.parseInt(mDetailModel.lcIndex);
		int chapterIndex = getIntent().getIntExtra(Constants.CURRENT_CHAPTER, -1);

		if (chapterIndex != -1) {
			mRCIndex = chapterIndex;
			if (mLCIndex < mRCIndex) {
				mLCIndex = mRCIndex;
			}
		}

		String bid = mDetailModel.id;
		String cid = mChapterModels.get(mRCIndex).id;
		int position = Integer.parseInt(mDetailModel.position);
		if (mFactory.resetChapter(false, bid, cid, position)) {
			mHandler.sendEmptyMessage(READ_CHAPTER);
			mExecutorService.execute(new NextChapterThread());
		} else {
			judgeBook();
		}
		addOnListener();
	}

	/**
	 * 
	 */
	private void judgeBook() {
		AppLog.e("into--[judgeBook]");
		int point = Integer.parseInt(mChapterModels.get(mRCIndex).points);
		AppLog.e("current chapter point:" + point);
		boolean isEnough = AppApplication.instance.points - point >= 0;
		boolean isAuto = Util.getAutoGetSharePreference(Constants.AUTO_GET);
		AppLog.e("isEnough:" + isEnough + " isAuto:" + isAuto);
		if (point == 0 || (isEnough && isAuto)) {
			AppLog.e("start download chapter");
			String url = AppConfig.CONTENT_HOST + mChapterModels.get(mRCIndex).url;
			AppLog.e("Rquest url:" + url);
			sendGetRequest(url, mAsyncLayout);
		} else {
			mNoPointsView.setVisibility(View.VISIBLE);
		}
		AppLog.e("out--[judgeBook]");
	}

	private void addOnListener() {
		mTitleView.setOnTitleListener(new OnTitleListener() {

			@Override
			public void onRight(View view) {
				mReadMenu.dismiss();
				startActivity(new Intent(getApplicationContext(), BookshelfActivity.class));
			}

			@Override
			public void onLeft(View view) {
				mReadMenu.dismiss();
				finish();
			}
		});

		mConsumeView.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				showConsumerMenu();
			}
		});
		mAsyncLayout.setOnHttpAsyncListner(new OnHttpAsyncListner() {

			@Override
			public void onSuccessListener(String url, String response) {
				AppLog.e("into--[onSuccessListener:]");

				if (TextUtils.equals("null", response)) {
					AppLog.e("into--[read next chapter!]");
					mRCIndex++;
					mHandler.sendEmptyMessage(LOAD_NEXT_CHAPTER);
					return;
				}

				int point = Integer.parseInt(mChapterModels.get(mRCIndex).points);
				AppConnect.getInstance(getApplicationContext()).spendPoints(point);
				AppApplication.instance.points -= point;
				AppLog.e("into--[Consume]" + point);
				AppLog.e("into--[Curren point]" + AppApplication.instance.points);
				mNetBookModel = JSON.parseObject(response, ContentModel.class);

				FileUtil.storeChapter(mNetBookModel.bid, mNetBookModel.id, mNetBookModel.content);
				mFactory.initChapter(mNetBookModel.bid, mNetBookModel.id);
				mHandler.sendEmptyMessage(READ_CHAPTER);

				if (mChapterModels == null) {
					return;
				}
				mLCIndex = mRCIndex;
				mLCIndex++;
				mExecutorService.execute(new NextChapterThread());
			}

			@Override
			public void onRefreshListener() {

			}

			@Override
			public void onErrorListener(VolleyError error) {

			}
		});

	}

	@Override
	protected void onPause() {
		super.onPause();

		DataBaseMannager.getInstance().updateValue(this, mDetailModel.id, BookShelfInfo.position, String.valueOf(mFactory.prePosition));
		DataBaseMannager.getInstance().updateValue(this, mDetailModel.id, BookShelfInfo.rcIndex, String.valueOf(mRCIndex));
		DataBaseMannager.getInstance().updateValue(this, mDetailModel.id, BookShelfInfo.lcIndex, String.valueOf(mLCIndex));
		DataBaseMannager.getInstance().updateValue(this, mDetailModel.id, BookShelfInfo.rPercent, mDetailModel.rPercent);

	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		isStop = true;
		mReadMenu.restDefaultSetting();
	}

	@Override
	public boolean handleMessage(Message msg) {

		switch (msg.what) {
		case READ_CHAPTER:
			readChapter();
			break;
		case READ_NEXT:
			readNextPage();
			break;
		case READ_PRE:
			readPrePage();
			break;

		case NIGT_MODEL:
			break;
		case DAY_MODEL:
			break;
		case READ_PRE_CHAPTER:
			readPreChapter();
			break;
		case READ_NEXT_CHAPTER:
			readNextChapter(msg.arg1);
			break;
		case RESET_REQUEST_POSITION:
			resetChapterPosition(msg.arg1);
			break;
		case CHANGE_TEXT_SIZE:
			changeTextSize(msg.arg1);
			break;
		case CHAGE_BACKGROUD:
			chageBackgroud(msg.arg1);
			break;
		case LOAD_NEXT_CHAPTER:
			loadNextChapter();
			break;
		default:
			return false;
		}
		showReadPercent();
		return true;
	}

	private void chageBackgroud(int arg1) {
		mReadView.setBackgroudColor(arg1);
		if (arg1 == getResources().getColor(R.color.backgroud_4)) {
			mPaint.setColor(getResources().getColor(R.color.read_color_night));
			mReadView.invalidate();
			mReadView.requestLayout();
		} else {
			mPaint.setColor(getResources().getColor(R.color.read_color));
			mReadView.invalidate();
			mReadView.requestLayout();
		}
	}

	// 修改字体大小

	private void changeTextSize(int increment) {
		mTextSize = Util.getIntBySharePreference(Constants.READ_TEXT_SIZE);
		if (mTextSize == 0) {
			mTextSize = 22;
		}
		mTextSize += increment;
		mPaint.setTextSize(mTextSize);
		mReadView.setTextSize(mPaint.getTextSize());

		mFactory.resetChapter(mPaint, mVisibleHeight / mReadView.getLineHeight());
		mHandler.sendEmptyMessage(READ_CHAPTER);

		Util.saveDataBySharePreference(Constants.READ_TEXT_SIZE, mTextSize);
	}

	private void resetChapterPosition(int arg1) {
		mFactory.resetChapter(true, mDetailModel.id, mChapterModels.get(mRCIndex).id, arg1);
		mHandler.sendEmptyMessage(READ_CHAPTER);
	}

	private void readNextChapter(int increment) {
		AppLog.e("into--[readNextChapter]");
		mRCIndex = increment == 0 ? ++mRCIndex : increment;
		if (mRCIndex >= mChapterModels.size()) {
			mRCIndex--;
		} else {
			boolean result = mFactory.initChapter(mDetailModel.id, mChapterModels.get(mRCIndex).id);
			AppLog.e("already load:" + result);
			if (!result) {
				judgeBook();
			} else {
				mHandler.sendEmptyMessage(READ_CHAPTER);
				AppLog.e("already load start next");
				mExecutorService.execute(new NextChapterThread());
			}
		}
		AppLog.e("out--[readNextChapter]");
	}

	private void loadNextChapter() {
		mConsumeMenu.dismiss();
		mNoPointsView.setVisibility(View.GONE);
		String url = AppConfig.CONTENT_HOST + mChapterModels.get(mRCIndex).url;
		sendGetRequest(url, mAsyncLayout);
		AppLog.e("consume url:" + url);
	}

	/**
	 * 
	 */
	private void showConsumerMenu() {
		int points = Integer.parseInt(mChapterModels.get(mRCIndex).points);

		boolean autoGet = Util.getAutoGetSharePreference(Constants.AUTO_GET);
		if (autoGet && (AppApplication.instance.points - points) > 0) {
			mNoPointsView.setVisibility(View.GONE);
			String url = AppConfig.CONTENT_HOST + mChapterModels.get(mRCIndex).url;
			sendGetRequest(url, mAsyncLayout);
		} else {
			mConsumeMenu.showConsumerMenu(mDetailModel.name, mChapterModels.get(mRCIndex).name, String.valueOf(points));
			// mRCIndex--;
		}
	}

	private void readPreChapter() {
		mRCIndex--;
		if (mRCIndex < 0) {
			mRCIndex = 0;
		} else {
			boolean result = mFactory.initChapter(mDetailModel.id, mChapterModels.get(mRCIndex).id);
			if (!result) {
				String url = AppConfig.CONTENT_HOST + mChapterModels.get(mRCIndex).url;
				sendGetRequest(url, mAsyncLayout);
			} else {
				mHandler.sendEmptyMessage(READ_CHAPTER);
			}
		}
	}

	private boolean readPrePage() {
		Vector<String> content = mFactory.prePage();
		if (content == null || content.size() == 0) {
			mRCIndex--;
			if (mRCIndex < 0) {
				Toast.makeText(getApplicationContext(), "第一页", Toast.LENGTH_SHORT).show();
				mRCIndex = 0;
				return true;
			}
			if (mChapterModels != null) {
				if (!mFactory.initPreChapter(mDetailModel.id, mChapterModels.get(mRCIndex).id)) {
					String url = AppConfig.CONTENT_HOST + mChapterModels.get(mRCIndex).url;
					sendGetRequest(url, mAsyncLayout);
				} else {
					mReadView.setPreText(mFactory.prePage());
				}
			}
		} else {
			mReadView.setPreText(content);
		}

		showReadPercent();
		return false;
	}

	private void showReadPercent() {
		double per = ((mRCIndex + 1) / (double) mChapterModels.size());
		mDetailModel.rPercent = Util.percentFormate(per);
		mReadProgressView.setText(mDetailModel.rPercent);
		mReadMenu.setRate(mChapterModels.size(), mRCIndex, mDetailModel.rPercent);

	}

	private boolean readNextPage() {
		AppLog.e("into--[readNextPage]");
		Vector<String> content = mFactory.nextPage();
		if (content == null || content.size() == 0) {
			if (mFactory.isFinish) {
				mRCIndex++;
				if (mRCIndex >= mChapterModels.size()) {
					Toast.makeText(getApplicationContext(), "最后一页", Toast.LENGTH_SHORT).show();
					mRCIndex--;
					return true;
				}

				if (mChapterModels != null) {
					if (!mFactory.initChapter(mDetailModel.id, mChapterModels.get(mRCIndex).id)) {
						judgeBook();
					} else {
						// handler.sendEmptyMessage(READ_NEXT);
						mReadView.setNextText(mFactory.nextPage());
						mExecutorService.execute(new NextChapterThread());
					}

				}
			}
		} else {
			mReadView.setNextText(content);
		}

		showReadPercent();
		AppLog.e("out--[readNextPage]");
		return false;
	}

	private void readChapter() {

		Vector<String> content = mFactory.nextPage();
		if (content != null) {
			mReadView.setCurrentText(content);
		}
	}

	float dx;
	float mx;
	float ux;

	boolean isFinish = false;
	boolean isRead = false;
	boolean isPreFinish = false;

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		int action = event.getAction();

		switch (action) {
		case MotionEvent.ACTION_DOWN:

			mReadMenu.dismiss();

			isPreFinish = false;
			dx = event.getX();
			break;
		case MotionEvent.ACTION_MOVE:
			mx = event.getX();
			float x = dx - mx;
			if (mx - dx < -0.1) {
				if (!isRead) {
					readNextPage();
					isRead = true;
				}
				mReadView.nextMove((int) (mReadView.getLeft() + x), 0);
			} else if (mx - dx > 0.1) {
				if (isPreFinish) {
					return true;
				}
				if (!isRead) {
					isRead = true;
					isPreFinish = readPrePage();
					if (isPreFinish) {
						return true;
					}

				}
				mReadView.preMove((int) (mReadView.getRight() + x), 0);
			}
			break;
		case MotionEvent.ACTION_UP:
			ux = event.getX();
			isRead = false;
			if (dx - ux > 0) {
				mReadView.nextScroll(dx - ux, 0);
			} else {
				mReadView.preScroll(ux - dx, 0);
			}
			break;
		default:
			break;
		}
		return super.onTouchEvent(event);
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		AppLog.e("into--[onKeyDown]");

		if (keyCode == KeyEvent.KEYCODE_BACK && mConsumeMenu.isShowing()) {
			mConsumeMenu.dismiss();
			return true;
		}

		if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU) {
			if (mReadMenu.onKeyDown(keyCode, event)) {
				return true;
			}
		}
		return super.onKeyDown(keyCode, event);
	}

	private OnHttpListener nextHttpListener = new OnHttpListener() {

		@Override
		public void onErrorResponse(VolleyError error) {
			AppLog.e(error.toString());
		}

		@Deprecated
		@Override
		public void onResponse(String response) {
		}

		@Override
		public void onHttpStart() {
		}

		@Override
		public void onResponse(boolean isCache, String url, String json) {
			AppLog.e("into--[onResponse]");

			if (TextUtils.equals("null", json)) {
				AppLog.e("response is empty!");
				mLCIndex++;
				mExecutorService.execute(new NextChapterThread());
				return;
			}

			int point = Integer.parseInt(mChapterModels.get(mLCIndex).points);
			AppConnect.getInstance(getApplicationContext()).spendPoints(point);
			AppApplication.instance.points -= point;
			ContentModel contentModel = JSON.parseObject(json, ContentModel.class);
			FileUtil.storeChapter(contentModel.bid, contentModel.id, contentModel.content);
			mLCIndex++;
			mExecutorService.execute(new NextChapterThread());
		}
	};

	class NextChapterThread extends Thread {

		@Override
		public void run() {
			AppLog.e("into--[NextChapterThread:run]");
			AppLog.e("mLCIndex:" + mLCIndex);
			AppLog.e("mRCIndex:" + mRCIndex);
			AppLog.e("isStop:" + isStop);
			if (!isStop && (mLCIndex - mRCIndex < CACHE_COUNT) && mLCIndex < mChapterModels.size()) {
				// 已经下载
				if (FileUtil.isLoadChapter(mDetailModel.id, mDetailModel.chapterModels.get(mLCIndex).id)) {
					mLCIndex++;
					AppLog.e("already load this chapter!");
					return;
				}
				int point = Integer.parseInt(mChapterModels.get(mLCIndex).points);
				boolean isEnough = AppApplication.instance.points - point >= 0;
				boolean isAuto = Util.getAutoGetSharePreference(Constants.AUTO_GET);
				AppLog.e("isEnough:" + isEnough + " isAuto:" + isAuto);
				if (point == 0 || (isEnough && isAuto)) {
					AppLog.e("start download NextChapter");
					String url = AppConfig.CONTENT_HOST + mChapterModels.get(mLCIndex).url;
					AppLog.e("NextChapter url:" + url);
					sendGetRequest(url, nextHttpListener);
				}
			}
		}
	}

}